package strategic_monitor

import (
	"context"
	"errors"
	"fmt"
	"git.mycaigou.com/gfyx/common/usermetadata"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/user"
	strategicMonitorRepo "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/business_opportunity/strategic_monitor"
	customerRepo "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/clue/customer"
	gfyxUserService "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/remote/gfyx_user_service_remote"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/remote/openapi_remote"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/remote/opensearch_remote"
	pb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/business_opportunity"
	gfyxUserServicePb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_user_service_proto/micro-gfyx-user-service"
	"strings"
	"time"
)

type strategicMonitorService struct {
	strategicMonitorRepo strategicMonitorRepo.StrategicMonitorRepoIface
	gfyxUserService      gfyxUserService.GfyxUserServiceRepositoryIface
	userRepo             user.UserRepositoryIface
	openApiRepo          openapi_remote.OpenApiRepoIface
	openSearchRepos      opensearch_remote.OpenSearchRepositoryIface
	customerRepo         customerRepo.CustomerManageRepositoryIface
}

func NewStrategicMonitorService(
	strategicMonitorRepo strategicMonitorRepo.StrategicMonitorRepoIface,
	gfyxUserService gfyxUserService.GfyxUserServiceRepositoryIface,
	userRepo user.UserRepositoryIface,
	openApiRepo openapi_remote.OpenApiRepoIface,
	openSearchRepos opensearch_remote.OpenSearchRepositoryIface,
	customerRepo customerRepo.CustomerManageRepositoryIface,
) StrategicMonitorServiceIface {
	return &strategicMonitorService{
		strategicMonitorRepo: strategicMonitorRepo,
		gfyxUserService:      gfyxUserService,
		userRepo:             userRepo,
		openApiRepo:          openApiRepo,
		openSearchRepos:      openSearchRepos,
		customerRepo:         customerRepo,
	}
}

func (s *strategicMonitorService) SubmitIndustry(ctx context.Context, request *pb.SubmitIndustryRequest) (*pb.SubmitIndustryResponse, error) {
	if request == nil || request.IndustryName == "" {
		return nil, errors.New("产品品类名称不能为空")
	}
	count, _, err := s.strategicMonitorRepo.QueryIndustryRecordList(ctx,
		map[string]interface{}{"industry_name": request.IndustryName, "is_deleted": constants.IsDeletedFalse},
		&utils.PageInfo{Page: 1, PageSize: 1})
	if err != nil {
		return nil, err
	}
	if count > 0 {
		return nil, errors.New("该品类已提交过，请勿重复提交")
	}

	industryData, err := s.gfyxUserService.GetIndustryByNames(ctx, &gfyxUserServicePb.GetIndustryByNamesRequest{
		IndustryNameArr: []string{request.IndustryName},
	})
	if err != nil {
		return nil, err
	}
	if industryData == nil {
		return nil, errors.New("提交品类失败，请稍后再试")
	}
	curUSer := usermetadata.GetMetaUserInfo(ctx)
	if len(industryData.List) > 0 {
		existIndustry := industryData.List[0]
		if existIndustry.AuditStatus == constants.StrategicAuditStatusPass {
			return nil, errors.New("提交失败，该品类已有历史审核通过记录，可在配置处直接添加监控")
		} else if existIndustry.AuditStatus == constants.StrategicAuditStatusReject {
			return nil, errors.New("提交失败，该品类已有历史审核不通过记录，可重新输入不同品类")
		}
	} else {
		_, err = s.gfyxUserService.AddIndustry(ctx, &gfyxUserServicePb.AddIndustryRequest{
			IndustryName: request.IndustryName,
			Operator:     curUSer.UserName,
			TenantCode:   curUSer.TenantCode,
		})
		if err != nil {
			return nil, err
		}
	}

	po, err := s.strategicMonitorRepo.SaveIndustryRecord(ctx, &strategicMonitorRepo.GfyxStrategicIndustryRecordPo{
		Id:           0,
		IndustryName: request.IndustryName,
		CreatedBy:    curUSer.UserId,
		CreatedOn:    time.Now(),
		ModifiedBy:   curUSer.UserId,
		ModifiedOn:   time.Now(),
		IsDeleted:    constants.IsDeletedFalse,
	})
	if err != nil {
		return nil, err
	}

	resp := &pb.SubmitIndustryResponse{
		Id: po.Id,
	}
	return resp, nil
}

func (s *strategicMonitorService) GetIndustryMonitorList(ctx context.Context, request *pb.GetIndustryMonitorListRequest) (*pb.GetIndustryMonitorListResponse, error) {
	_, list, err := s.strategicMonitorRepo.QueryIndustryMonitorList(ctx,
		map[string]interface{}{"is_deleted": constants.IsDeletedFalse, "monitor_status": constants.StrategicMonitorStatusWatching}, nil, "")
	if err != nil {
		return nil, err
	}
	resp := &pb.GetIndustryMonitorListResponse{
		Total: 0,
	}
	if len(list) == 0 {
		return resp, nil
	}
	var industryNames []string
	var createdUserIds []int64
	userIdSet := make(map[int64]bool)
	for _, item := range list {
		industryNames = append(industryNames, item.IndustryName)
		if _, ok := userIdSet[item.CreatedBy]; !ok {
			userIdSet[item.CreatedBy] = true
			createdUserIds = append(createdUserIds, item.CreatedBy)
		}
	}
	// 从gfyx_user_service获取产品品类的审核状态信息
	industryData, err := s.gfyxUserService.GetIndustryByNames(ctx, &gfyxUserServicePb.GetIndustryByNamesRequest{
		IndustryNameArr: industryNames,
	})
	if err != nil {
		return nil, err
	}
	industryMap := make(map[string]*gfyxUserServicePb.IndustryItem)
	if industryData != nil && len(industryData.List) > 0 {
		for _, item := range industryData.List {
			industryMap[item.IndustryName] = item
		}
	}

	userIdMap := make(map[int64]*user.GfyxUserPo)
	if len(createdUserIds) != 0 {
		_, userList, err := s.userRepo.QueryUserList(ctx,
			map[string]interface{}{"id": createdUserIds, "is_deleted": constants.IsDeletedFalse}, &utils.PageInfo{Page: 1, PageSize: len(createdUserIds)}, "")
		if err != nil {
			return nil, err
		}
		for _, userItem := range userList {
			userIdMap[userItem.Id] = userItem
		}
	}

	for _, item := range list {
		if industryItem, ok := industryMap[item.IndustryName]; ok {
			if industryItem.AuditStatus == constants.StrategicAuditStatusPass {
				pbIndustryItem := &pb.IndustrySubmitItem{
					Id:              item.Id,
					IndustryName:    item.IndustryName,
					MonitorStatus:   item.MonitorStatus,
					BidCompanyCount: industryItem.BidCompanyCount,
					CreatedBy:       "",
					CreatedOn:       item.CreatedOn.Format("2006-01-02 15:04:05"),
					AuditStatus:     industryItem.AuditStatus,
				}
				if createdUser, ok := userIdMap[item.CreatedBy]; ok {
					pbIndustryItem.CreatedBy = createdUser.Name
				}
				resp.List = append(resp.List, pbIndustryItem)
			} else {
				//产品品类的审核状态变更未待审核或审核不通过，那么监控中的品类也要变成未监控
				_ = s.strategicMonitorRepo.UpdateIndustryMonitor(ctx,
					map[string]interface{}{"id": item.Id},
					map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWaiting})
			}
		}
	}

	resp.Total = int32(len(resp.List))
	return resp, nil
}

func (s *strategicMonitorService) GetIndustrySubmitList(ctx context.Context, request *pb.GetIndustrySubmitListRequest) (*pb.GetIndustrySubmitListResponse, error) {
	total, list, err := s.strategicMonitorRepo.QueryIndustryRecordList(ctx, map[string]interface{}{"is_deleted": constants.IsDeletedFalse},
		&utils.PageInfo{Page: int(request.Page), PageSize: int(request.PageSize)})
	if err != nil {
		return nil, err
	}
	resp := &pb.GetIndustrySubmitListResponse{
		Total: int32(total),
	}
	if len(list) == 0 {
		return resp, nil
	}
	var industryNames []string
	var createdUserIds []int64
	userIdSet := make(map[int64]bool)
	for _, item := range list {
		industryNames = append(industryNames, item.IndustryName)
		if _, ok := userIdSet[item.CreatedBy]; !ok {
			userIdSet[item.CreatedBy] = true
			createdUserIds = append(createdUserIds, item.CreatedBy)
		}
	}

	// 从gfyx_user_service获取产品品类的审核状态信息
	industryData, err := s.gfyxUserService.GetIndustryByNames(ctx, &gfyxUserServicePb.GetIndustryByNamesRequest{
		IndustryNameArr: industryNames,
	})
	if err != nil {
		return nil, err
	}
	industryMap := make(map[string]*gfyxUserServicePb.IndustryItem)
	if industryData != nil && len(industryData.List) > 0 {
		for _, item := range industryData.List {
			industryMap[item.IndustryName] = item
		}
	}

	// 从产品品类监控表中获取监控状态
	_, monitorList, err := s.strategicMonitorRepo.QueryIndustryMonitorList(ctx,
		map[string]interface{}{"industry_name": industryNames, "is_deleted": constants.IsDeletedFalse},
		&utils.PageInfo{Page: 1, PageSize: len(industryNames)}, "")
	if err != nil {
		return nil, err
	}

	industryMonitorStatusMap := make(map[string]int32)
	for _, item := range monitorList {
		industryMonitorStatusMap[item.IndustryName] = item.MonitorStatus
	}

	userIdMap := make(map[int64]*user.GfyxUserPo)
	if len(createdUserIds) != 0 {
		_, userList, err := s.userRepo.QueryUserList(ctx,
			map[string]interface{}{"id": createdUserIds, "is_deleted": constants.IsDeletedFalse}, &utils.PageInfo{Page: 1, PageSize: len(createdUserIds)}, "")
		if err != nil {
			return nil, err
		}
		for _, userItem := range userList {
			userIdMap[userItem.Id] = userItem
		}
	}

	for _, item := range list {
		pbItem := &pb.IndustrySubmitItem{
			Id:              item.Id,
			IndustryName:    item.IndustryName,
			MonitorStatus:   0,
			BidCompanyCount: 0,
			CreatedBy:       "",
			CreatedOn:       item.CreatedOn.Format("2006-01-02 15:04:05"),
			AuditStatus:     0,
		}

		if createdUser, ok := userIdMap[item.CreatedBy]; ok {
			pbItem.CreatedBy = createdUser.Name
		}
		if industryItem, ok := industryMap[item.IndustryName]; ok {
			pbItem.AuditStatus = industryItem.AuditStatus
			pbItem.BidCompanyCount = industryItem.BidCompanyCount
		}
		if industryMonitorStatus, ok := industryMonitorStatusMap[item.IndustryName]; ok {
			// 如果品类审核状态不是审核通过，那么监控中的状态要变成无监控状态，即0
			if industryMonitorStatus == 2 && pbItem.AuditStatus != constants.StrategicAuditStatusPass {
				pbItem.MonitorStatus = 0
				_ = s.strategicMonitorRepo.UpdateIndustryMonitor(ctx,
					map[string]interface{}{"industry_name": item.IndustryName, "is_deleted": constants.IsDeletedFalse},
					map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusDefault})
			}
			pbItem.MonitorStatus = industryMonitorStatus
		}

		resp.List = append(resp.List, pbItem)
	}

	return resp, nil
}

func (s *strategicMonitorService) ChangeIndustryMonitorStatus(ctx context.Context, request *pb.ChangeIndustryMonitorStatusRequest) (*pb.ChangeIndustryMonitorStatusResponse, error) {
	if request == nil || len(request.IndustryNameList) == 0 {
		return nil, errors.New("参数不能为空")
	}
	if len(request.IndustryNameList) > 5 {
		return nil, errors.New("监控的产品品类不能超过5个")
	}
	//如果监控过的品类数超过5个，那么每个月仅允许一次修改品类
	count, _, err := s.strategicMonitorRepo.QueryIndustryMonitorList(ctx, map[string]interface{}{"is_deleted": constants.IsDeletedFalse}, utils.FirstPageFirstRecord, "")
	if err != nil {
		return nil, err
	}
	onceMonthSwitch := false
	if count >= 5 {
		onceMonthSwitch = true
	}

	if onceMonthSwitch {
		//看最后一条监控记录是否是本月修改的，如果是，那么说明本月的操作次数已用完
		_, list, err := s.strategicMonitorRepo.QueryIndustryMonitorList(ctx,
			map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWatching, "is_deleted": constants.IsDeletedFalse},
			utils.FirstPageFirstRecord, "modified_on desc")
		if err != nil {
			return nil, err
		}
		if len(list) > 0 {
			lastItem := list[0]
			if lastItem.ModifiedOn.Format("2006-01") == time.Now().Format("2006-01") {
				return nil, errors.New("本月修改监控品类次数已用完，请下个月再来")
			}
		}
	}
	industryData, err := s.gfyxUserService.GetIndustryByNames(ctx, &gfyxUserServicePb.GetIndustryByNamesRequest{
		IndustryNameArr: request.IndustryNameList,
	})
	if err != nil {
		return nil, err
	}
	industryMap := make(map[string]*gfyxUserServicePb.IndustryItem)
	if industryData != nil && len(industryData.List) > 0 {
		for _, item := range industryData.List {
			industryMap[item.IndustryName] = item
		}
	}
	for _, industryName := range request.IndustryNameList {
		industryItem, ok := industryMap[industryName]
		if !ok {
			//分类名称在平台不存在，可能是运营在战图删除了该品类
			return nil, fmt.Errorf("品类[%s]不存在，请先提交该品类，通过审核后即可监控", industryName)
		}
		if industryItem.AuditStatus != constants.StrategicAuditStatusPass {
			//分类在平台不是审核通过的，不能选中
			return nil, fmt.Errorf("品类[%s]还未通过审核，请重新选择品类", industryName)
		}
	}

	_, list, err := s.strategicMonitorRepo.QueryIndustryMonitorList(ctx, map[string]interface{}{"industry_name": request.IndustryNameList, "is_deleted": constants.IsDeletedFalse},
		&utils.PageInfo{Page: 1, PageSize: len(request.IndustryNameList)}, "")
	if err != nil {
		return nil, err
	}
	existIndustryNameSet := make(map[string]bool)
	for _, item := range list {
		existIndustryNameSet[item.IndustryName] = true
	}

	curUser := usermetadata.GetMetaUserInfo(ctx)
	_ = s.strategicMonitorRepo.UpdateIndustryMonitor(ctx, map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWatching, "is_deleted": constants.IsDeletedFalse},
		map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWaiting, "modified_by": curUser.UserId, "modified_on": time.Now()})
	for _, industryName := range request.IndustryNameList {
		industryItem, ok := industryMap[industryName]
		if !ok {
			//分类名称在平台不存在，可能是运营在战图删除了该品类
			return nil, fmt.Errorf("品类[%s]不存在，请先提交该品类，通过审核后即可监控", industryName)
		}
		if industryItem.AuditStatus != constants.StrategicAuditStatusPass {
			//分类在平台不是审核通过的，不能选中
			return nil, fmt.Errorf("品类[%s]还未通过审核，请重新选择品类", industryName)
		}
		if _, exist := existIndustryNameSet[industryName]; exist {
			// 如果分类名称已经在gfyx_strategic_industry_monitor表中，更新监控状态和修改时间
			err = s.strategicMonitorRepo.UpdateIndustryMonitor(ctx,
				map[string]interface{}{"industry_name": industryName, "is_deleted": constants.IsDeletedFalse},
				map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWatching, "modified_by": curUser.UserId, "modified_on": time.Now()})
			if err != nil {
				return nil, err
			}
		} else {
			// 如果分类名称不在gfyx_strategic_industry_monitor表中，新增记录
			_, err = s.strategicMonitorRepo.SaveIndustryMonitor(ctx, &strategicMonitorRepo.GfyxStrategicIndustryMonitorPo{
				Id:            0,
				IndustryName:  industryName,
				MonitorStatus: constants.StrategicMonitorStatusWatching,
				CreatedBy:     curUser.UserId,
				CreatedOn:     time.Now(),
				ModifiedBy:    curUser.UserId,
				ModifiedOn:    time.Now(),
				IsDeleted:     constants.IsDeletedFalse,
			})
			if err != nil {
				return nil, err
			}
		}
	}

	return &pb.ChangeIndustryMonitorStatusResponse{IsSuccess: true}, nil
}

func (s *strategicMonitorService) GetIndustryStat(ctx context.Context, request *pb.GetIndustryStatRequest) (*pb.GetIndustryStatResponse, error) {
	count, _, err := s.strategicMonitorRepo.QueryIndustryRecordList(ctx, map[string]interface{}{"is_deleted": constants.IsDeletedFalse}, utils.FirstPageFirstRecord)
	if err != nil {
		return nil, err
	}
	data, err := s.GetIndustryMonitorList(ctx, &pb.GetIndustryMonitorListRequest{})
	if err != nil {
		return nil, err
	}
	return &pb.GetIndustryStatResponse{
		SubmitCount:  int32(count),
		MonitorCount: data.Total,
	}, nil
}

func (s *strategicMonitorService) SubmitCompany(ctx context.Context, request *pb.SubmitCompanyRequest) (*pb.SubmitCompanyResponse, error) {
	if request == nil || request.CompanyName == "" {
		return nil, errors.New("参数不能为空")
	}
	//1.检查公司是否提交过
	count, _, err := s.strategicMonitorRepo.QueryCompanyRecordList(ctx,
		map[string]interface{}{"company_name": request.CompanyName, "is_deleted": constants.IsDeletedFalse},
		utils.FirstPageFirstRecord)
	if err != nil {
		return nil, err
	}
	if count > 0 {
		return nil, errors.New("该公司已提交过，请勿重复提交")
	}
	//2.检查工商信息是否存在
	companyDetail, err := s.openApiRepo.GetCompanyDetail(ctx, request.CompanyName)
	if err != nil {
		return nil, errors.New("企业工商信息不存在，请核对后重新输入")
	}
	if companyDetail == nil || companyDetail.OrganizingCode == "" {
		return nil, errors.New("企业工商信息不存在，请核对后重新输入")
	}

	//3.检查是否是已审核的
	companyData, err := s.gfyxUserService.GetBidCompanyByCodes(ctx, &gfyxUserServicePb.GetBidCompanyByCodesRequest{
		OrganizingCodeArr: []string{companyDetail.OrganizingCode},
	})
	if err != nil {
		return nil, err
	}
	if companyData == nil {
		return nil, errors.New("提交客户失败，请稍后再试")
	}

	curUser := usermetadata.GetMetaUserInfo(ctx)
	if len(companyData.List) > 0 {
		existCompany := companyData.List[0]
		if existCompany.AuditStatus == constants.StrategicAuditStatusPass {
			return nil, errors.New("提交失败，该客户已有历史审核通过记录，可在配置处直接添加监控")
		} else if existCompany.AuditStatus == constants.StrategicAuditStatusReject {
			return nil, errors.New("提交失败，该客户已有历史审核不通过记录，可重新输入其他客户名称")
		}
	} else {
		_, err = s.gfyxUserService.AddBidCompany(ctx, &gfyxUserServicePb.AddBidCompanyRequest{
			CompanyName: request.CompanyName,
			Operator:    curUser.UserName,
			TenantCode:  curUser.TenantCode,
		})
		if err != nil {
			return nil, err
		}
	}

	companyPo, err := s.strategicMonitorRepo.SaveCompanyRecord(ctx, &strategicMonitorRepo.GfyxStrategicCompanyRecordPo{
		Id:             0,
		CompanyName:    request.CompanyName,
		OrganizingCode: companyDetail.OrganizingCode,
		CreatedBy:      curUser.UserId,
		CreatedOn:      time.Now(),
		ModifiedBy:     curUser.UserId,
		ModifiedOn:     time.Now(),
		IsDeleted:      constants.IsDeletedFalse,
	})
	if err != nil {
		return nil, err
	}

	resp := &pb.SubmitCompanyResponse{Id: companyPo.Id}
	return resp, nil
}

func (s *strategicMonitorService) GetCompanyMonitorList(ctx context.Context, request *pb.GetCompanyMonitorListRequest) (*pb.GetCompanyMonitorListResponse, error) {
	_, list, err := s.strategicMonitorRepo.QueryCompanyMonitorList(ctx,
		map[string]interface{}{"is_deleted": constants.IsDeletedFalse, "monitor_status": constants.StrategicMonitorStatusWatching}, nil)
	if err != nil {
		return nil, err
	}
	resp := &pb.GetCompanyMonitorListResponse{
		Total: 0,
	}
	if len(list) == 0 {
		return resp, nil
	}
	var organizingCodes []string
	var createdUserIds []int64
	userIdSet := make(map[int64]bool)
	for _, item := range list {
		organizingCodes = append(organizingCodes, item.OrganizingCode)
		if _, ok := userIdSet[item.CreatedBy]; !ok {
			userIdSet[item.CreatedBy] = true
			createdUserIds = append(createdUserIds, item.CreatedBy)
		}
	}
	// 从gfyx_user_service获取公司品类的审核状态信息
	companyData, err := s.gfyxUserService.GetBidCompanyByCodes(ctx, &gfyxUserServicePb.GetBidCompanyByCodesRequest{
		OrganizingCodeArr: organizingCodes,
	})
	if err != nil {
		return nil, err
	}
	bidCompanyMap := make(map[string]*gfyxUserServicePb.BidCompanyItem)
	if companyData != nil && len(companyData.List) > 0 {
		for _, item := range companyData.List {
			bidCompanyMap[item.OrganizingCode] = item
		}
	}

	userIdMap := make(map[int64]*user.GfyxUserPo)
	if len(createdUserIds) != 0 {
		_, userList, err := s.userRepo.QueryUserList(ctx,
			map[string]interface{}{"id": createdUserIds, "is_deleted": constants.IsDeletedFalse}, &utils.PageInfo{Page: 1, PageSize: len(createdUserIds)}, "")
		if err != nil {
			return nil, err
		}
		for _, userItem := range userList {
			userIdMap[userItem.Id] = userItem
		}
	}

	for _, item := range list {
		if companyItem, ok := bidCompanyMap[item.OrganizingCode]; ok {
			if companyItem.AuditStatus == constants.StrategicAuditStatusPass {
				pbCompanyItem := &pb.CompanySubmitItem{
					Id:             item.Id,
					CompanyName:    item.CompanyName,
					OrganizingCode: item.OrganizingCode,
					MonitorStatus:  item.MonitorStatus,
					BidCount:       companyItem.BidCount,
					CreatedBy:      "",
					CreatedOn:      item.CreatedOn.Format("2006-01-02 15:04:05"),
					AuditStatus:    companyItem.AuditStatus,
				}
				if createdUser, ok := userIdMap[item.CreatedBy]; ok {
					pbCompanyItem.CreatedBy = createdUser.Name
				}
				resp.List = append(resp.List, pbCompanyItem)
			} else {
				//企业的审核状态变更未待审核或审核不通过，那么监控中的品类也要变成未监控
				_ = s.strategicMonitorRepo.UpdateCompanyMonitor(ctx,
					map[string]interface{}{"id": item.Id},
					map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWaiting})
			}
		}
	}

	resp.Total = int32(len(resp.List))
	return resp, nil
}

func (s *strategicMonitorService) GetCompanySubmitList(ctx context.Context, request *pb.GetCompanySubmitListRequest) (*pb.GetCompanySubmitListResponse, error) {
	total, list, err := s.strategicMonitorRepo.QueryCompanyRecordList(ctx, map[string]interface{}{"is_deleted": constants.IsDeletedFalse},
		&utils.PageInfo{Page: int(request.Page), PageSize: int(request.PageSize)})
	if err != nil {
		return nil, err
	}
	resp := &pb.GetCompanySubmitListResponse{
		Total: int32(total),
	}
	if len(list) == 0 {
		return resp, nil
	}
	var organizingCodes []string
	var createdUserIds []int64
	userIdSet := make(map[int64]bool)
	for _, item := range list {
		organizingCodes = append(organizingCodes, item.OrganizingCode)
		if _, ok := userIdSet[item.CreatedBy]; !ok {
			userIdSet[item.CreatedBy] = true
			createdUserIds = append(createdUserIds, item.CreatedBy)
		}
	}

	// 从gfyx_user_service获取客户的审核状态信息
	companyData, err := s.gfyxUserService.GetBidCompanyByCodes(ctx, &gfyxUserServicePb.GetBidCompanyByCodesRequest{
		OrganizingCodeArr: organizingCodes,
	})
	if err != nil {
		return nil, err
	}
	companyMap := make(map[string]*gfyxUserServicePb.BidCompanyItem)
	if companyData != nil && len(companyData.List) > 0 {
		for _, item := range companyData.List {
			companyMap[item.OrganizingCode] = item
		}
	}

	// 从客户监控表中获取监控状态
	_, monitorList, err := s.strategicMonitorRepo.QueryCompanyMonitorList(ctx,
		map[string]interface{}{"organizing_code": organizingCodes, "is_deleted": constants.IsDeletedFalse},
		&utils.PageInfo{Page: 1, PageSize: len(organizingCodes)})
	if err != nil {
		return nil, err
	}

	companyMonitorStatusMap := make(map[string]int32)
	for _, item := range monitorList {
		companyMonitorStatusMap[item.OrganizingCode] = item.MonitorStatus
	}

	userIdMap := make(map[int64]*user.GfyxUserPo)
	if len(createdUserIds) != 0 {
		_, userList, err := s.userRepo.QueryUserList(ctx,
			map[string]interface{}{"id": createdUserIds, "is_deleted": constants.IsDeletedFalse}, &utils.PageInfo{Page: 1, PageSize: len(createdUserIds)}, "")
		if err != nil {
			return nil, err
		}
		for _, userItem := range userList {
			userIdMap[userItem.Id] = userItem
		}
	}

	for _, item := range list {
		pbItem := &pb.CompanySubmitItem{
			Id:             item.Id,
			CompanyName:    item.CompanyName,
			OrganizingCode: item.OrganizingCode,
			MonitorStatus:  0,
			BidCount:       0,
			CreatedBy:      "",
			CreatedOn:      item.CreatedOn.Format("2006-01-02 15:04:05"),
			AuditStatus:    0,
		}

		if createdUser, ok := userIdMap[item.CreatedBy]; ok {
			pbItem.CreatedBy = createdUser.Name
		}
		if companyItem, ok := companyMap[item.OrganizingCode]; ok {
			pbItem.AuditStatus = companyItem.AuditStatus
			pbItem.BidCount = companyItem.BidCount
		}
		if monitorStatus, ok := companyMonitorStatusMap[item.OrganizingCode]; ok {
			// 如果公司的审核状态不是审核通过，那么监控中的状态要变成无监控状态，即0
			if monitorStatus == 2 && pbItem.AuditStatus != constants.StrategicAuditStatusPass {
				pbItem.MonitorStatus = 0
				_ = s.strategicMonitorRepo.UpdateCompanyMonitor(ctx,
					map[string]interface{}{"organizing_code": item.OrganizingCode, "is_deleted": constants.IsDeletedFalse},
					map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusDefault})
			}
			pbItem.MonitorStatus = monitorStatus
		}

		resp.List = append(resp.List, pbItem)
	}

	return resp, nil
}

func (s *strategicMonitorService) ChangeCompanyMonitorStatus(ctx context.Context, request *pb.ChangeCompanyMonitorStatusRequest) (*pb.ChangeCompanyMonitorStatusResponse, error) {
	if request == nil || len(request.List) == 0 {
		return nil, errors.New("参数不能为空")
	}

	var organizingCodes []string
	for _, item := range request.List {
		organizingCodes = append(organizingCodes, item.OrganizingCode)
	}

	industryData, err := s.gfyxUserService.GetBidCompanyByCodes(ctx, &gfyxUserServicePb.GetBidCompanyByCodesRequest{
		OrganizingCodeArr: organizingCodes,
	})
	if err != nil {
		return nil, err
	}
	bidCompanyMap := make(map[string]*gfyxUserServicePb.BidCompanyItem)
	if industryData != nil && len(industryData.List) > 0 {
		for _, item := range industryData.List {
			bidCompanyMap[item.OrganizingCode] = item
		}
	}
	for _, item := range request.List {
		bidCompanyInfo, ok := bidCompanyMap[item.OrganizingCode]
		if !ok {
			//客户在平台不存在，可能是运营在战图删除了该客户
			return nil, fmt.Errorf("客户[%s]不存在，请先提交该客户，通过审核后即可监控", item.CompanyName)
		}
		if bidCompanyInfo.AuditStatus != constants.StrategicAuditStatusPass {
			//分类在平台不是审核通过的，不能选中
			return nil, fmt.Errorf("客户[%s]还未通过审核，请重新选择客户", item.CompanyName)
		}
	}
	_, list, err := s.strategicMonitorRepo.QueryCompanyMonitorList(ctx, map[string]interface{}{"organizing_code": organizingCodes, "is_deleted": constants.IsDeletedFalse},
		&utils.PageInfo{Page: 1, PageSize: len(organizingCodes)})
	if err != nil {
		return nil, err
	}
	existCompanyOrganizingCodeSet := make(map[string]bool)
	for _, item := range list {
		existCompanyOrganizingCodeSet[item.OrganizingCode] = true
	}

	curUser := usermetadata.GetMetaUserInfo(ctx)
	_ = s.strategicMonitorRepo.UpdateCompanyMonitor(ctx, map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWatching, "is_deleted": constants.IsDeletedFalse},
		map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWaiting, "modified_by": curUser.UserId, "modified_on": time.Now()})
	for _, item := range request.List {
		if _, exist := existCompanyOrganizingCodeSet[item.OrganizingCode]; exist {
			// 如果客户已经在gfyx_strategic_company_monitor表中，更新监控状态和修改时间
			err = s.strategicMonitorRepo.UpdateIndustryMonitor(ctx,
				map[string]interface{}{"organizing_code": item.OrganizingCode, "is_deleted": constants.IsDeletedFalse},
				map[string]interface{}{"monitor_status": constants.StrategicMonitorStatusWatching, "modified_by": curUser.UserId, "modified_on": time.Now()})
			if err != nil {
				return nil, err
			}
		} else {
			// 如果客户不在gfyx_strategic_company_monitor表中，新增记录
			_, err = s.strategicMonitorRepo.SaveCompanyMonitor(ctx, &strategicMonitorRepo.GfyxStrategicCompanyMonitorPo{
				Id:             0,
				CompanyName:    item.CompanyName,
				OrganizingCode: item.OrganizingCode,
				MonitorStatus:  constants.StrategicMonitorStatusWatching,
				CreatedBy:      curUser.UserId,
				CreatedOn:      time.Now(),
				ModifiedBy:     curUser.UserId,
				ModifiedOn:     time.Now(),
				IsDeleted:      constants.IsDeletedFalse,
			})
			if err != nil {
				return nil, err
			}
		}
	}

	return &pb.ChangeCompanyMonitorStatusResponse{IsSuccess: true}, nil
}

func (s *strategicMonitorService) GetCompanyStat(ctx context.Context, request *pb.GetCompanyStatRequest) (*pb.GetCompanyStatResponse, error) {
	count, _, err := s.strategicMonitorRepo.QueryCompanyRecordList(ctx, map[string]interface{}{"is_deleted": constants.IsDeletedFalse}, utils.FirstPageFirstRecord)
	if err != nil {
		return nil, err
	}
	data, err := s.GetCompanyMonitorList(ctx, &pb.GetCompanyMonitorListRequest{})
	if err != nil {
		return nil, err
	}
	return &pb.GetCompanyStatResponse{
		SubmitCount:  int32(count),
		MonitorCount: data.Total,
	}, nil
}

func (s *strategicMonitorService) GetMonitorResult(ctx context.Context, request *pb.GetMonitorResultRequest) (*pb.GetMonitorResultResponse, error) {
	industryMonitorList, err := s.GetIndustryMonitorList(ctx, &pb.GetIndustryMonitorListRequest{})
	if err != nil {
		return nil, err
	}
	companyMonitorList, err := s.GetCompanyMonitorList(ctx, &pb.GetCompanyMonitorListRequest{})
	if err != nil {
		return nil, err
	}
	var industryNameList, companyOrganizingCodeList []string
	if industryMonitorList != nil && len(industryMonitorList.List) > 0 {
		for _, item := range industryMonitorList.List {
			industryNameList = append(industryNameList, item.IndustryName)
		}
	}
	if companyMonitorList != nil && len(companyMonitorList.List) > 0 {
		for _, item := range companyMonitorList.List {
			companyOrganizingCodeList = append(companyOrganizingCodeList, item.OrganizingCode)
		}
	}
	data, err := s.gfyxUserService.GetMonitorResult(ctx, &gfyxUserServicePb.GetMonitorResultRequest{
		IndustryNameList:   industryNameList,
		OrganizingCodeList: companyOrganizingCodeList,
		Page:               request.Page,
		PageSize:           request.PageSize,
	})
	if err != nil {
		return nil, err
	}
	if data == nil {
		return nil, errors.New("获取数据失败")
	}
	resp := &pb.GetMonitorResultResponse{
		Total:                data.Total,
		IndustryMonitorCount: int32(len(industryNameList)),
	}
	var organizingCodes []string
	for _, item := range data.List {
		organizingCodes = append(organizingCodes, item.OrganizingCode)
	}
	//调用openSearch获取客户详情
	customerDetailList, err := s.openSearchRepos.GetCustomerDetail(ctx, &opensearch_remote.GetCustomerDetailRequest{OrganizingCodes: strings.Join(organizingCodes, ",")})
	if err != nil {
		return nil, err
	}
	customerDetailMap := make(map[string]*opensearch_remote.CustomerDetail)
	for _, customerDetail := range customerDetailList {
		customerDetailMap[customerDetail.OrganizingCode] = customerDetail
	}
	_, existCustomerList, _ := s.customerRepo.QuerySimpleCustomerList(ctx, map[string]interface{}{"organizing_codes": organizingCodes, "is_deleted": constants.IsDeletedFalse}, nil)
	existCustomerMap := make(map[string]bool)
	for _, customerPo := range existCustomerList {
		existCustomerMap[customerPo.OrganizingCode] = true
	}
	for _, item := range data.List {
		pbItem := &pb.MonitorResultItem{
			CompanyName:              item.CompanyName,
			OrganizingCode:           item.OrganizingCode,
			CompanyLogo:              "",
			CompanyIdentity:          nil,
			CompanyType:              "",
			BidCnt_2Year:             0,
			TakeLandCnt_2Year:        0,
			CommencePermitCnt_2Year:  0,
			SellProjectCnt_2Year:     0,
			CooperationCaseCnt_2Year: 0,
			ContactNum:               0,
			IsExistCustomer:          existCustomerMap[item.OrganizingCode],
			Province:                 "",
			ProvinceCode:             "",
			City:                     "",
			CityCode:                 "",
			StrategicDynamic:         nil,
			CooperateCompany:         nil,
		}
		if customerDetail, ok := customerDetailMap[item.OrganizingCode]; ok {
			if customerDetail.IsDeveloper == 1 {
				pbItem.CompanyIdentity = append(pbItem.CompanyIdentity, constants.CompanyIdentityDeveloper)
			}
			if customerDetail.IsSupplier == 1 {
				pbItem.CompanyIdentity = append(pbItem.CompanyIdentity, constants.CompanyIdentitySupplier)
			}
			// 拼接logo
			if customerDetail.DeveloperId != "" && !strings.HasPrefix(customerDetail.DeveloperLogo, "http") {
				pbItem.CompanyLogo = utils.GetCompanyLogoUrl(customerDetail.DeveloperId, customerDetail.DeveloperLogo)
			}
			pbItem.CompanyType = customerDetail.CompanyType
			pbItem.Province = customerDetail.Province
			pbItem.ProvinceCode = customerDetail.ProvinceCode
			pbItem.City = customerDetail.City
			pbItem.CityCode = customerDetail.CityCode
			pbItem.ContactNum = customerDetail.ContactNum
			pbItem.BidCnt_2Year = customerDetail.BidCnt2Year
			pbItem.TakeLandCnt_2Year = customerDetail.TakeLandCnt2Year
			pbItem.CommencePermitCnt_2Year = customerDetail.CommencePermitCnt2Year
			pbItem.SellProjectCnt_2Year = customerDetail.SellProjectCnt2Year
			pbItem.CooperationCaseCnt_2Year = customerDetail.CooperationCaseCnt2Year
		}

		for _, dynamic := range item.StrategicDynamic {
			pbItem.StrategicDynamic = append(pbItem.StrategicDynamic, &pb.StrategicDynamic{
				Id:                dynamic.Id,
				ProcureType:       dynamic.ProcureType,
				PublishDate:       dynamic.PublishDate,
				Title:             dynamic.Title,
				DeduceNextBidDate: dynamic.DeduceNextBidDate,
			})
		}
		for _, cooperateCompany := range item.CooperateCompany {
			pbItem.CooperateCompany = append(pbItem.CooperateCompany, &pb.CooperateCompany{
				CooperateCompanyName: cooperateCompany.CooperateCompanyName,
				PublishDate:          cooperateCompany.PublishDate,
				IndustryNames:        cooperateCompany.IndustryNames,
			})
		}
		resp.List = append(resp.List, pbItem)
	}

	return resp, nil
}
